<template>
  <el-form :label-position="formContext.labelPosition" :inline="true" ref="formRef">
    <el-row ref="resizeRef" class="query-form-row" :gutter="gutter">
      <slot />
      <el-col :span="controlSpan" v-if="isControl" class="form-item-control">
        <el-form-item>
          <template #label v-if="isControlLabel"> &nbsp; </template>
          <slot
            name="control"
            :collapse="collapse"
            :overflow="overflow"
            :toggleCollapse="toggleCollapse"
            :resetFields="resetFields"
          />
          <div v-if="overflow" class="query-collapse-button" @click="toggleCollapse()">
            <el-button type="primary" link>
              {{ collapse ? $t('form.expand') : $t('form.shrink') }}
              <i class="icon">
                <Icon :icon="collapse ? 'uiw:down' : 'uiw:up'" />
              </i>
            </el-button>
          </div>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
<script setup>
import { ref, watch, computed, provide, getCurrentInstance, useSlots, useTemplateRef } from 'vue'
import { useResize } from '@/hooks/use-resize.js'
import { useSpanConfig } from '@/components/form/hook/use-span-config.js'
import useOrderedChildren from '@/hooks/use-ordered-children.js'
import { beforeDebounce } from '@/utils/util.js'
import { Icon } from '@iconify/vue'

const props = defineProps({
  labelPosition: {
    type: String,
    values: ['left', 'right', 'top'],
    default: 'right',
  },
  span: {
    // 响应式断点
    type: [Number, Array],
    default: null,
  },
  gutter: {
    // 栅格间隔
    type: Number,
    default: 16,
  },
  collapsed: {
    // 是否折叠超出的表单项
    type: Boolean,
    default: false,
  },
  defaultCollapsed: {
    // 默认状态下是否折叠超出的表单项
    type: Boolean,
    default: true,
  },
})

const slots = useSlots()
const emit = defineEmits(['collapse'])
const formRef = useTemplateRef('formRef')
const width = ref()
const resizeRef = ref()
const collapse = ref(props.defaultCollapsed) // 是否展开
const overflow = ref(false) // 是否显示展开收缩

const formContext = useSpanConfig(width, props.span, props.labelPosition, props.gutter)
const instance = getCurrentInstance()
// 是否显示控制列 collapsed 或者 有control插槽时 现在显示控制列
const isControl = computed(() => {
  return props.collapsed || slots.control
})

const {
  children: formItems,
  addChild: registerForm,
  removeChild: unregisterForm,
} = useOrderedChildren(instance, 'QueryFormItem')

const setWidth = beforeDebounce(({ target }) => {
  const client = target.getBoundingClientRect()
  width.value = client.width
}, 10)

useResize(resizeRef, setWidth)

provide(formContextKey, {
  formItems,
  registerForm,
  unregisterForm,
  form: formContext,
  overflow: overflow.value,
})

// 控制列的列宽
const controlSpan = computed(() => {
  const { span } = formContext.value
  return span
})

// 是否展示控制列的label
const isControlLabel = computed(() => {
  const { span, labelPosition } = formContext.value
  return !(span === 24 && labelPosition === 'top')
})

/**
 * 监听并且设置列的显隐藏
 */
watch([collapse, formContext.value, () => formItems.value], () => {
  if (props.collapsed !== true) {
    return
  }
  // 当前每列的列宽
  const eachSpan = formContext.value.span
  let spanSum = eachSpan
  overflow.value = false
  formItems.value.forEach((item, index) => {
    item.index = index
    spanSum += item.span ?? eachSpan

    item.visible = false
    if (spanSum > 24) {
      overflow.value = true
      if (collapse.value && index > 0) {
        item.visible = true
      }
    }
  })
})

const toggleCollapse = () => {
  collapse.value = !collapse.value
  emit('collapse', collapse.value)
}
const resetFields = () => {
  formRef?.value?.resetFields()
}

defineExpose({
  formRef,
  resetFields,
})
</script>
<script>
import { formContextKey } from '@/components/form/utils.js'
</script>

<style scoped lang="scss">
.query-form-row {
  width: 100%;
  /* row-gap: 24px;*/
  .form-item-control {
    margin-right: 0;
    margin-left: auto;
    display: inline-flex;
    align-items: start;
    justify-content: end;

    :deep(.el-form-item) {
      margin-right: 0;
      .el-form-item__label {
        flex: 0 1 auto;
      }
      .el-form-item__content {
        flex: 1 0 auto;
      }
      .el-button + .el-button {
        margin-left: 12px;
      }
      .query-collapse-button {
        margin-left: 12px;
        > button {
          letter-spacing: 1px;
        }
        .icon {
          margin-left: 4px;
        }
      }
    }
  }
  :deep(.query-form-item) {
    box-sizing: border-box;
    .el-form-item {
      margin-bottom: 24px;
      margin-right: 0;
      width: 100%;
      .el-form-item__content {
        .el-input,
        .el-select {
          width: 100%;
        }
      }
    }
  }
}
</style>
